package cn.aitrox.ry.util;

import cn.aitrox.ry.bean.JwtTokenCheckResult;
import cn.aitrox.ry.enumtype.RespCodeEnum;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.apache.commons.lang3.StringUtils;

import java.util.Date;
import java.util.Map;

public class JwtUtils {

    private static final String CUSTOM_CLAIM = "CUSTOM_CLAIM";

    public static <T> String genToken(String secret, Integer expiresAtSeconds, T payload) {
        try {
            Date now = new Date();
            Date expireDate = DateUtil.addSecond(now, expiresAtSeconds);

            String payloadJson = JSONUtil.toJson(payload, payload.getClass());

            String jwtToken = JWT.create()
                    .withClaim(CUSTOM_CLAIM, payloadJson)
                    .withExpiresAt(expireDate)
                    .withIssuedAt(now)
                    .sign(Algorithm.HMAC256(secret));
            return jwtToken;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 判断token是否存在与有效
     *
     * @Param jwtToken
     */
    public static <T> JwtTokenCheckResult<T> checkToken(String secret, String jwtToken, Class<T> clazz) {
        if (StringUtils.isEmpty(jwtToken)) {
            return new JwtTokenCheckResult(RespCodeEnum.TOKEN_MISS, null, null);
        }
        //验证token
        DecodedJWT verify;
        try {
            verify = JWT.require(Algorithm.HMAC256(secret)).build().verify(jwtToken);
        } catch (TokenExpiredException e) {
            return new JwtTokenCheckResult(RespCodeEnum.LOGIN_EXPIRED, null, null);
        } catch (JWTVerificationException e) {
            return new JwtTokenCheckResult(RespCodeEnum.TOKEN_INVALID, null, null);
        }
        try {
            Map<String, Claim> claims = verify.getClaims();
            Claim claim = claims.get(CUSTOM_CLAIM);
            String payloadJson = claim.asString();
            T customPayload = JSONUtil.fromJson(payloadJson, clazz);
            Date expiresAt = verify.getExpiresAt();
            return new JwtTokenCheckResult(RespCodeEnum.SUCCESS, customPayload, expiresAt);
        } catch (Exception e) {
            return new JwtTokenCheckResult(RespCodeEnum.TOKEN_INVALID, null, null);
        }
    }
}


